Skip to content

feat(contracts): enforce EIP-7825 gas cap in NUT bundle validation#20205

Merged
maurelian merged 6 commits intoethereum-optimism:developfrom
defi-wonderland:feat/contracts-nut-bundle-gas-cap
Apr 23, 2026
Merged

feat(contracts): enforce EIP-7825 gas cap in NUT bundle validation#20205
maurelian merged 6 commits intoethereum-optimism:developfrom
defi-wonderland:feat/contracts-nut-bundle-gas-cap

Conversation

@lumoswiz
Copy link
Copy Markdown
Contributor

@lumoswiz lumoswiz commented Apr 21, 2026

Description

Adds a per-transaction EIP-7825 gas cap check to GenerateNUTBundle._assertValidOutput. Any NUT bundle transaction whose gasLimit exceeds the Osaka cap (2**24 = 16_777_216) is now rejected at bundle-generation time rather than at execution.

The EIP-7623 calldata floor check already landed in #20075. This PR folds it together with the new upper cap into a single bounded-range require:

  • Lower bound: EIP-7623 calldata floor (UpgradeUtils.computeFloorDataGas).
  • Upper bound: EIP-7825 per-tx cap (MAX_TX_GAS_LIMIT = 2**24).

Also refactors GenerateNUTBundle to separate orchestration from bundle construction so tests can validate bundles without writing the artifact:

  • run() runs setUp, then _buildOutput, then _assertValidOutput, then writeArtifact.
  • _buildOutput() builds the Output struct with no disk I/O.
  • _assertValidOutput() performs all validation checks.

A GenerateNUTBundle_Harness test contract exposes buildOutput() and assertValidOutput() externally. This lets fuzz iterations validate bundles without racing on CURRENT_BUNDLE_PATH.

Tests

Full negative-path coverage for every branch in _assertValidOutput was added to test/scripts/GenerateNUTBundle.t.sol. Each test follows the same pattern:

  • Invoke script.buildOutput() (harness) to produce a valid bundle
  • Mutate a single field (or the array length)
  • Assert that script.assertValidOutput reverts with the expected error message

Cases covered:

  • Transaction count mismatch
  • Empty data
  • Empty intent
  • Zero to
  • gasLimit above the EIP-7825 cap
  • gasLimit of zero (rejected by the floor)
  • gasLimit one below the EIP-7623 floor
  • Zero from paired with a non-privileged to

The count-mismatch test uses assembly to rewrite the in-memory array length rather than rebuilding the array. Shrink-only, because growing would blow up the ABI encoding on the external call to assertValidOutput.

Additional context

Issue #20109 calls for two checks: the EIP-7825 upper cap and an op-geth EIP-7623 floor. The floor portion was resolved by #20075. This PR adds the remaining cap check and consolidates the two into one range check.

Metadata

Closes #20109

@0xOneTony
Copy link
Copy Markdown
Contributor

/ci authorize 0885ccf

Comment thread packages/contracts-bedrock/scripts/upgrade/GenerateNUTBundle.s.sol Outdated
Comment thread packages/contracts-bedrock/test/scripts/GenerateNUTBundle.t.sol
@lumoswiz lumoswiz marked this pull request as ready for review April 22, 2026 15:32
@lumoswiz lumoswiz requested review from a team and skeletor-spaceman April 22, 2026 15:32
@0xOneTony
Copy link
Copy Markdown
Contributor

/ci authorize 51ae847

@0xOneTony
Copy link
Copy Markdown
Contributor

/ci authorize 1d470ff

@maurelian maurelian added this pull request to the merge queue Apr 23, 2026
Merged via the queue into ethereum-optimism:develop with commit 1f70eba Apr 23, 2026
129 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[L2CM] Ensure all bundle tx fit within Osaka gas limit and op-geth gas floor

5 participants